#ifndef __CAN_CANOPEN_H_
#define __CAN_CANOPEN_H_

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "stm32f10x_bkp.h"
#include "Global.h"
#include "can.h"
#include "Display.h"
#include "Rtc.h"
#include "menu.h"
#include "var_tbl.h"
#include "system.h"

/********************************************************************************************************
*Macros
********************************************************************************************************/


#define FILTER_MASK                                     0x7FF    // 111 1001 1111 // message type 1111 00 master id 11111 slave id 

#define SHIFT_5_BITS                                    5

#define STD_MASK                                        0xFFE0 // 1111 1111 1110 // message type 1111 11 master id 11111 slave id 

#define CANOPEN_TRAC_CAL_TX_ID                          0x781   // To traction
#define CANOPEN_LIFT_CAL_TX_ID                          0x782   // To Tilt
#define CANOPEN_TRAC_CAL_RX_ID                          0x791   // from traction
#define CANOPEN_LIFT_CAL_RX_ID                          0x792   // from Tilt

// KWP ID     
#define DISP_KWP_RX_ID_ALL                              0x780   // KWP RX Id
#define DISP_KWP_RX_ID                                  0x784   // KWP RX Id
#define DISP_KWP_TX_ID                                  0x794   // KWP TX Id

//BR1189
//Display
#define DISP_PDO1_TX_ID                                 0x184   //1000ms Transmit

//Steer
#define BR1189_STEER_PDO1_RX_ID                                0x183   //10ms Receive
#define BR1189_STEER_PDO3_RX_ID                                0x383   //400ms Receive
//Traction
#define BR1189_TRAC_PDO1_RX_ID                          0x181   //10ms Receive
#define BR1189_TRAC_PDO3_RX_ID                          0x381   //400ms Receive
#define BR1189_TRAC_PDO5_RX_ID1                         0x304
#define BR1189_TRAC_PDO5_RX_ID2                         0x581
//Lift
#define BR1189_LIFT_PDO1_RX_ID                          0x182   //10ms Receive    
#define BR1189_LIFT_PDO3_RX_ID                          0x382   //400ms Receive
#define SYNC_MSG_PDO_RX                                 0x80 

#define CAN_OPEN_NMT_ENABLED                            0x0001
#define CAN_OPEN_SDO_ENABLED                            0x0002
#define CAN_OPEN_PDO_ENABLED                            0x0004
#define CAN_OPEN_HEARTBEAT_ENABLED                      0x0008
#define CAN_OPEN_EMERGENCY_ENABLED                      0x0010
#define CAN_OPEN_EMERGENCY_RCV_ENABLED                  0x0020
#define CANOPEN_HEARTBEAT_RCV_ENABLED                   0x0040
#define CAN2_CANOPEN_ENABLED                            0x0100
#define CAN1_CANOPEN_ENABLED                            0x0200


#define	E_TX_BUFF_SIZE	                32


// Externally Declared Constants
#define NMT_INITIALIZATION				                0


// These are the control specifiers passed by the master to force entry into a state
#define NMT_CS_START_REMOTE_NODE                        1
#define NMT_CS_STOP_REMOTE_NODE                         2
#define NMT_CS_ENTER_PRE_OPERATIONAL                    128
#define NMT_CS_RESET_NODE                               129
#define NMT_CS_RESET_COMMUNICATION                      130

// Externally Declared Constants
#define NMT_INITIALIZATION				                0
#define NMT_STOPPED						                4
#define NMT_OPERATIONAL					                5
#define NMT_PRE_OPERATIONAL				                127

enum
{
    CAN_STD_ID,
    CAN_EXT_ID
};

struct CAN_SYSTEM_BITS
{
    int CAN_Enabled:1;
    int CAN_PDO_Timed_Out:1;
    int CAN_Write_EE_CAN:1;
    int CAN_PDO_Timeouts_On:1;
    int CAN_PDO_Enabled:1;
    int CAN_SDO_Enabled:1;
    int CAN_SDO_Block_Download:1;
    int CAN_SDO_Block_DISConnect:1;
    int CAN_Message_Center_Unpdate:1;
};

union CAN_SYSTEM_FLAGS
{
    s16                     all;
    struct CAN_SYSTEM_BITS  bit;
};
extern union CAN_SYSTEM_FLAGS CanSystemFlags;

/** Security States */
enum secacc_state
{
   secacc_state_default       =  0x00,  /**< No security level          */
   secacc_state_programming   =  0x01,  /**< Programming State          */
   secacc_state_service       =  0x03,  /**< Field Flash                */
   secacc_state_eopl          =  0x05   /**< End Of Production Line     */
};

typedef struct
{
    u8 hourmeter_counter_flag;
	u8 pump_oil_level;
	u8 motor_over_tempurate;
	u8 fets_over_tempurate;
}Lift_PDO1_Type;
extern Lift_PDO1_Type BR1189_lift_status;

typedef struct 
{
    u16 steer_wheel_angle;
	u8 steer_speed_status;
	u8 hourmeter_counter_flag;
	u8 motor_over_tempurate;
	u8 fets_over_tempurate;	
}Steer_PDO1_Type;

typedef struct
{
    u8 active_oil_level;
	u8 buzzer_warning;
	u8 foot_platfm_sw;
	u8 tiller_foot_sw;
	u8 seat_sw;
	u8 platfm_pos;
	u8 left_guardr;
	u8 right_guardr;
	u8 track_id;
	u8 battery_lock;
	u8 hourmeter_counter_flag;
	u8 driver_present;
	u8 motor_over_tempurate;
	u8 fets_over_tempurate;	
}Trac_PDO1_Type;

/** Fortune object */
struct fortune
{
   u32 random;
};
/** Standard KWP2000 error codes */
enum kwp_response_code
{
   KWP_RESPONSE_CODE_GENERALREJECT                    = 0x10,
   KWP_RESPONSE_CODE_SERVICENOTSUPPORTED              = 0x11,
   KWP_RESPONSE_CODE_SUBFUNCTIONNOTSUPPORTED          = 0x12,
   KWP_RESPONSE_CODE_INVALIDFORMAT                    = 0x12,
   KWP_RESPONSE_CODE_BUSYREPEATREQUEST                = 0x21,
   KWP_RESPONSE_CODE_CONDITIONSNOTCORRECT             = 0x22,
   KWP_RESPONSE_CODE_REQUESTSEQUENCEERROR             = 0x22,
   KWP_RESPONSE_CODE_ROUTINENOTCOMPLETED              = 0x23,
   KWP_RESPONSE_CODE_REQUESTOUTOFRANGE                = 0x31,
   KWP_RESPONSE_CODE_RESPONSEPENDING                  = 0x78,
   KWP_RESPONSE_CODE_SERVICENOTSUPPORTEDINACTIVEMODE  = 0x80,
   KWP_RESPONSE_CODE_ACCESSDENIED                     = 0x33,
   KWP_RESPONSE_CODE_INVALIDKEY                       = 0x35,
   KWP_RESPONSE_CODE_EXCEEDNUMOFATTEMPTS              = 0x36,
   KWP_RESPONSE_CODE_TIMEDELAYNOTEXPIRED              = 0x37,
   KWP_RESPONSE_CODE_DOWNLOADNOTACCEPTED              = 0x40,
   KWP_RESPONSE_CODE_IMPROPERDOWNLOADTYPE             = 0x41,
   KWP_RESPONSE_CODE_CANNTDOWNLOADTOADDRESS           = 0x42,
   KWP_RESPONSE_CODE_CANNTDOWNLOADNUMOFBYTES          = 0x43,
   KWP_RESPONSE_CODE_UPLOADNOTACCEPTED                = 0x50,
   KWP_RESPONSE_CODE_IMPROPERUPLOADTYPE               = 0x51,
   KWP_RESPONSE_CODE_CANNTUPLOADFROMADDRESS           = 0x52,
   KWP_RESPONSE_CODE_CANNTUPLOADNUMOFBYTES            = 0x53,
   KWP_RESPONSE_CODE_TRANSFERSUSPENDED                = 0x71,
   KWP_RESPONSE_CODE_TRANSFERABORTED                  = 0x72,
   KWP_RESPONSE_CODE_ILLEGALADDRESSINBLOCKTRANSFER    = 0x74,
   KWP_RESPONSE_CODE_ILLEGALBYTECOUNTINBLOCKTRANSFER  = 0x75,
   KWP_RESPONSE_CODE_ILLEGALBLOCKTRANSFERTYPE         = 0x76,
   KWP_RESPONSE_CODE_BLOCKTRANSFERDATACHECKSUMERROR   = 0x77,
   KWP_RESPONSE_CODE_INCORRECTBYTECNTDGBLOCKTRANSFER  = 0x79,
   KWP_RESPONSE_CODE_INVALIDCHECKSUM                  = 0xFB,
   KWP_RESPONSE_CODE_NONE                             = 0x00
};
enum kwpdiag_sid
{
    startDiagnosticSession              = 0x10,
    ecuReset                            = 0x11,
    readDiagnosticTroubleCodes          = 0x13,
    clearDiagnosticInformation          = 0x14,
    readStatusOfDiagnosticTroubleCodes  = 0x17,
    readDiagnosticTroubleCodesByStatus  = 0x18,
    readECUIdentification               = 0x1A,
    stopDiagnosticSession               = 0x20,
    readDataByLocalIdentifier           = 0x21,
    ReadDataByCommonIdentifier          = 0x22,
    readMemoryByAddress                 = 0x23,
    securityAccess                      = 0x27,
    WriteDataByCommonIdentifier         = 0x2E,
    inputOutputControlByLocalIdentifier = 0x30,
    startRoutineByLocalIdentifier       = 0x31,
    requestDownload                     = 0x34,
    transferData                        = 0x36,
    requestTransferExit                 = 0x37,
    writeDataByLocalIdentifier          = 0x3B,
    testerPresent                       = 0x3E
};

#define HM_COUNTER_ON                           0x01
#define HM_COUNTER_OFF                          0x00
#define OIL_LACK                                0x01
#define OIL_OK                                  0x00
#define TEMPURATE_OVER                          0x01
#define TEMPURATE_OK                            0x00
#define BUZZER_ON                               0x01
#define BUZZER_OFF                              0x00
#define SW_PRESSED                              0x01
#define SW_NOTPRESSED                           0x00
#define IN_PLACE                                0x01
#define NOT_IN_PLACE                            0x00
#define GUARDRAIL_COLSED                        0x01
#define GUARDRAIL_NOT_COLSED                    0x00
#define TRACK_ID_EUQAL                          0x01
#define TRACK_ID_DIFF                           0x00
#define BAT_LOCK                                0x01
#define BAR_NOT_LOCK                            0x00
#define DRIVER_ON                               0x01
#define DRIVER_NOT_ON                           0x00

#define CAN_Enabled                     CanSystemFlags.bit.CAN_Enabled
#define CAN_PDO_Timed_Out               CanSystemFlags.bit.CAN_PDO_Timed_Out
#define CAN_Write_EE_CAN                CanSystemFlags.bit.CAN_Write_EE_CAN
#define CAN_PDO_Timeouts_On             CanSystemFlags.bit.CAN_PDO_Timeouts_On
#define CAN_PDO_Enabled                 CanSystemFlags.bit.CAN_PDO_Enabled
#define CAN_SDO_Enabled                 CanSystemFlags.bit.CAN_SDO_Enabled
#define CAN_SDO_Blk_Download            CanSystemFlags.bit.CAN_SDO_Block_Download
#define CAN_SDO_Blk_DISConnect          CanSystemFlags.bit.CAN_SDO_Block_DISConnect

#define KWP_START_DEFAULT_SESSION                       0x10
#define KWP_DEFAULT_SESSION                             0x81
#define KWP_START_DEFAULT_SESSION_OK                    0x50

#define KWP_SINGLE_FRM                                  0x00    // single frame
#define KWP_RD_ECU                                      0x1A  // read ecu
#define RD_ECU_OK                                       0x5A
#define KWP_FAIL                                        0x7F
#define KWP_FUN_NOT_SUPPORT                             0x12

#define KWP_RD_DATA                                     0x21   // Read data by local id
#define KWP_RD_DATA_OK                                  0x61

#define FOUR_BYTES_LEN                                  4
#define TWO_BYTES_LEN                                   2
#define ONE_BYTES_LEN                                   1

#define KWP_WR_DATA                                     0x3B   // write data by local id
#define KWP_WR_DATA_OK                                  0x7B
#define KWP_OUTOF_RAGNGE                                0x31

#define KWP_SECURITY                                    0x27
#define KWP_SECURITY_OK                                 0x67

#define KWP_ECU_RESET                                   0x11                      
#define KWP_ECU_RESET_OK                                0x51 

#define KWP_LEVEL_1                                     1
#define KWP_LEVEL_2                                     2
#define KWP_LEVEL_3                                     3
#define KWP_SECURITY_DENIED                             0x33

/** Security Access 1/2 supported */
#define SECACC_12                                       1

/** Security Access 3/4 supported */
#define SECACC_34                                       1

/** Security Access 5/6 supported */
#define SECACC_56                                       1

#define KWP_ROUTINE_INC_1                               0x10  // Increase with step 1
#define KWP_ROUTINE_INC_10                              0x11  // Increase with step 10
#define KWP_ROUTINE_DEC_1                               0x12  // Dec with step 1
#define KWP_ROUTINE_DEC_10                              0x13  // Increase with step 10
#define KWP_ROUTINE_SET_DEF                             0x18  // set default
#define KWP_ROUTINE_RESET_DEF                           0xF0  // reset to default
#define KWP_REQUEST_OUT_OF_RANGE                        0x31
                                                        
#define KWP_START_ROUTINE                               0x31  // read ecu
#define KWP_START_ROUTINE_OK                            0x71
#define KWP_START_FLASH                                 0x01  
#define KWP_DEL_FLASH                                   0x02    
#define KWP_CAL_CHECKSUM                                0x03                                                        
#define KWP_PASSIVE_MODE                                0x04   
#define KWP_INIT01_REQ                                  0x80    

#define DEADDROP_RAM_ADDR   0x2000BFF0U
#define DEADDROP_RAM_ADDR   0x2000BFF0U
/**
* 	Address of the Deaddrop
*	This defines the start address for a deaddrop structure.
*/
#define DEADDROP_ADR ((void*)DEADDROP_RAM_ADDR)
    
/**
* 	Pointer to the deaddrop structure
* 	This macro defines a pointer from type struct deaddrop to a specific address.
* 	It will be used to access the content of the struct.
* 	But care has to be taken because the linker does not know about the use of this
* 	memory area for this purpose.
*/
#define deaddrop_p  ((struct deaddrop* ) DEADDROP_ADR )
    
/**
*	Deaddrop Structure
*	The deaddrop structure is used to exchange information between the BOOT_BLOCK and
*	the CDX20_APPLIKATION.
*/
struct deaddrop
{
	U32 stay_in_bb_flag; 		/**< Set by APP read and cleared by BB */
	U32 start_application_flag;	/**< Only used by BB */
	U32 reset_reason;			/**< Set by BB read by APP */
};
#define KWP_FLASH_FLAG     0xAAFF0055

#define KWP_RD_DTC                                      0x13  // read DTC
#define KWP_RD_DTC_OK                                   0x53  // read DTC
#define KWP_RD_SDTC                                     0x17  // read status of DTC
#define KWP_RD_SDTC_OK                                  0x57  // read status of DTC

#define KWP_GATEWAY_TRAC_ADDR                           0x01
#define KWP_GATEWAY_LIFT_ADDR                           0x02

#define KWP_CLR_DTC                                     0x14  // clear DTC
#define KWP_CLR_DTC_OK                                  0x54  // clear DTC

#define KWP_RD_DATA_BY_CMD_ID                           0x22   // Read data by local id
#define KWP_RD_DATA_BY_CMD_ID_OK                        0x62
#define KWP_FIRSET_FRAME                                0x01    // first frame-segmented transfer

#define KWP_FLOW_CONTROL_FRM                            0x03    // flow control frame

#define CONTINUE_TO_SEND                                0x00    // continue to send
#define KWP_MIN_INTERVAL                                0x0A
#define CONSECUTIVE_FRM                                 0x02    // flow control frame
extern s16 can_pdo_timeout;
extern u16 br1189_traction_timeout;
extern u16 br1189_lift_timeout;
extern u8 can_pdo_data[8];
extern E_STORED_FAULT_PARAM br1347_traction_stored_fault[MAX_STORED_FAULT];
extern E_STORED_FAULT_PARAM br1347_lift_stored_fault[MAX_STORED_FAULT];
extern E_STORED_FAULT_PARAM br1275_bms_stored_fault[MAX_STORED_FAULT];
extern E_STORED_FAULT_PARAM rfid_stored_fault[MAX_STORED_FAULT];
extern s8 kwp_needs_ee;
extern u8 kwp_ee_index;
extern u16 display_total_stored_fault;

/* Function declaration ------------------------------------------------------*/
extern void process_msg(CanRxMsg* RxMessage);
extern int canopen_init(void);
extern void can2_send_timestamp(void);
extern void CAN_set_tx_msg_to_buff(CanTxMsg* TxMessage);
extern void can_tx_msg_from_buff(void);
extern void can_send_timestamp(void);
extern void secacc_set_state( enum secacc_state state );
extern void kwp_period_transmit(void);
extern void can_send_heartbeat(u8 can_status);
extern void can_send_heartbeat_operational(void);
extern Lift_PDO1_Type BR1189_lift_status;
extern Steer_PDO1_Type BR1189_steer_status;
extern Trac_PDO1_Type BR1189_trac_status;
extern s16 can_nmt_state;
extern u8 test_can_buff[8];
extern void can_send_testtamp(U8 *databuf);
extern u8 test_can_transmit_buf[8];
#endif
